/*
 * 
 * 
 * 
 */
package com.hboxs.asl.service.impl;

import com.hboxs.asl.dao.SpecificationValueDao;
import com.hboxs.asl.entity.Product;
import com.hboxs.asl.entity.Specification;
import com.hboxs.asl.entity.SpecificationValue;
import com.hboxs.asl.service.SpecificationValueService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * Service - 规格值
 */
@Service("specificationValueServiceImpl")
public class SpecificationValueServiceImpl extends BaseServiceImpl<SpecificationValue, Long> implements SpecificationValueService {

    @Resource(name = "specificationValueDaoImpl")
    public void setBaseDao(SpecificationValueDao specificationValueDao) {
        super.setBaseDao(specificationValueDao);
    }

    @Override
    public boolean checkExist(Long[] ids) {
        if (ids == null) {
            return false;
        }
        boolean flag = false;
        if (ids.length != 0) {
            flag = true;
        }
        for (Long id : ids) {
            if (super.find(id) == null) {
                flag = false;
            }
        }
        return flag;
    }

    @Override
    public boolean checkPossess(Product product, Long[] ids) {
        Set<SpecificationValue> all = new HashSet<>();
        for (Product p : product.getGoods().getProducts()) {
            all.addAll(p.getSpecificationValues());
        }
        for (Long id : ids) {
            if (!all.contains(super.find(id))) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean checkSame(Long[] ids) {
        Set<Specification> set = new HashSet<>();
        for (Long id : ids) {
            SpecificationValue val = super.find(id);
            if (val != null) {
                set.add(val.getSpecification());
            }
        }
        return set.size() == ids.length;
    }

    @Override
    public Set<Long> findDisableIds(Product product, Long[] ids) {
        Set<Long> disableIds = new HashSet<>();
        Set<SpecificationValue> disables = new HashSet<>();
        if (product == null || ids.length == 0) {
            return null;
        }
        List<Product> brothers = product.getGoods().getProducts();
        //商品全部规格值
        Set<SpecificationValue> allVals = new HashSet<>();
        for (Product brother : brothers) {
            allVals.addAll(brother.getSpecificationValues());
        }
        Set<SpecificationValue> selectedVals = new HashSet<>();
        for (Long id : ids) {
            selectedVals.add(super.find(id));
        }
        //接下来循环每个被选中的规格值，得出每一种对应的其他不可选的规格值
        for (SpecificationValue selectedVal : selectedVals) {
            Set<SpecificationValue> otherVals = new HashSet<>(selectedVals);
            otherVals.remove(selectedVal);
            //可选的规格值
            Set<SpecificationValue> avails = new HashSet<>();
            for (Product b : brothers) {
                if (b.getSpecificationValues().size() != 0 && b.getSpecificationValues().contains(selectedVal)) {
                    avails.addAll(b.getSpecificationValues());
                }

            }
            Set<SpecificationValue> disableVals = new HashSet<>(allVals);
            disableVals.removeAll(avails);
            //在移除所选规格的
            Iterator<SpecificationValue> it = disableVals.iterator();
            while (it.hasNext()) {
                SpecificationValue s = it.next();
                if (s.getSpecification().equals(selectedVal.getSpecification())) {
                    it.remove();
                }
            }
            disables.addAll(disableVals);
        }
        for (SpecificationValue d : disables) {
            disableIds.add(d.getId());
        }
        disableIds.removeAll(new HashSet<>(Arrays.asList(ids)));
        return disableIds;
    }

    @Override
    public Product findProductBySpecVals(Product product, Long[] ids) {
        Product target = null;
        //2.迭代所有规格商品,找到 规格值集合的长度和specIds长度相等,并且规格值的id和specIds相等
        for (Product p : product.getGoods().getProducts()) {
            if (p.getSpecificationValues().size() == ids.length && contains(p, ids)) {
                target = p;
            }
        }
        return target;
    }

    /**
     * 判断商品是否包含该种规格
     *
     * @param p       商品
     * @param specIds 规格值id
     * @return boolean
     */
    protected Boolean contains(Product p, Long[] specIds) {

        Boolean contains = true;
        Set<SpecificationValue> specValues = p.getSpecificationValues();
        for (Long id : specIds) {
            if (!specValues.contains(super.find(id))) {
                contains = false;
            }
        }

        return contains;
    }

    @Override
    public Set<Long> notPossess(Product product) {
        if (product==null){
            return null;
        }
        Set<Long> disableIds = new HashSet<>();
        Set<SpecificationValue> allVals = new HashSet<>();
        Set<Specification> specs = product.getSpecifications();
        for (Specification spec : specs) {
            allVals.addAll(spec.getSpecificationValues());
        }
        Set<SpecificationValue> possessVals = product.getGoods().getSpecificationValues();
        allVals.removeAll(possessVals);
        for (SpecificationValue allVal : allVals) {
            disableIds.add(allVal.getId());
        }
        return disableIds;
    }
}